import 'package:flutter/material.dart';
import 'package:flutter_boost/flutter_boost.dart';
import 'package:flutter_map_demo/poi_search/page/poi_search_page_controller.dart';
import 'package:flutter_map_demo/poi_search/widget/poi_list/poi_footer.dart';
import 'package:flutter_slidable/flutter_slidable.dart';
import 'package:t3_data_service/biz_data_source/map/address/poi_search/model/t3_poi_enums.dart';
import 'package:t3_foundation/t3_foundation.dart';
import 'package:t3_track/t3_track.dart';
import 'package:uikit/uikit.dart';
import 'package:flutter/services.dart';

import '../../configs/poi_search_base_config.dart';
import '../model/const.dart';
import '../model/section_model.dart';
import '../view_model/poi_search_cell_view_model.dart';
import '../widget/entry_widget/entry_widget.dart';
import '../widget/poi_list/poi_cell.dart';
import '../widget/poi_list/poi_header.dart';
import '../widget/search_bar/search_bar_widget.dart';

/// 搜索Page
/// 关闭页面时返回选址列表
/// {'data' : List<POIModel.json>}
class PoiSearchPage extends StatefulWidget {
  final POISearchBaseConfig searchConfig;

  const PoiSearchPage({
    Key? key,
    required this.searchConfig,
  }) : super(key: key);

  @override
  _PoiSearchPageState createState() => _PoiSearchPageState();
}

class _PoiSearchPageState extends State<PoiSearchPage>
    with PageVisibilityObserver {
  late POISearchPageController controller;
  late ValueChanged<List<POISearchCellViewModel>> onFinishSelection;
  late ValueChanged<Map> onMapFinishSelection;
  final ScrollController _scrollController = ScrollController();
  var didExposureFeedback = false;

  @override
  void onPageShow() {
    controller.reportOnPageShow();
    print('autoOpenCity:   --------onPageShow');
    SystemUiOverlayStyle systemUiOverlayStyle = const SystemUiOverlayStyle(
        statusBarColor: Color(0x00FF0000),
        statusBarIconBrightness: Brightness.dark);
    SystemChrome.setSystemUIOverlayStyle(systemUiOverlayStyle);
  }

  @override
  void onPageHide() {
  }

  @override
  void onForeground() {
    controller.reportOnForeground();
  }

  @override
  void onBackground() {
  }

  @override
  void initState() {

    super.initState();

    /// 搜索结果
    onFinishSelection = (List<POISearchCellViewModel> vms) {
      var pageScene = widget.searchConfig.pageScene;
      if (pageScene == PageScene.feedback) {
        controller.openFeedBack(vms.safeAccess(0));
      } else {
        List<Map<String, dynamic>> result = [];
        for (var item in vms) {
          final ele = item.jsonOutput(pageScene != PageScene.normal);
          if (widget.searchConfig.isStartPoint) {
            ele["addrtype"] = 0;
          } else {
            ele["addrtype"] = 1;
          }
          result.add(ele);
        }
        BoostNavigator.instance.pop({'data': result,});
      }
    };

    _scrollController.addListener(dismissKeyboard);

    controller = POISearchPageController(widget.searchConfig);
    controller.getRemoteCommonUserAddress(context, widget.searchConfig);
    controller.showShareGuideCallback(widget.searchConfig, (showGuide) {
      if (showGuide) {
        FocusScope.of(context).requestFocus(FocusNode());
        controller.showShareGuide(context);
      }
    });
  }

  void dismissKeyboard() {
    FocusScope.of(context).requestFocus(FocusNode());
  }

  @override
  void didChangeDependencies() {
    super.didChangeDependencies();
    PageVisibilityBinding.instance.addObserver(this, ModalRoute.of(context)!);
  }

  @override
  void dispose() {
    PageVisibilityBinding.instance.removeObserver(this);
    _scrollController.removeListener(dismissKeyboard);
    controller.dispose();
    _scrollController.dispose();

    SystemUiOverlayStyle systemUiOverlayStyle = const SystemUiOverlayStyle(
        statusBarColor: Colors.transparent);
    SystemChrome.setSystemUIOverlayStyle(systemUiOverlayStyle);
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    String navigationBarTitle = '';
    if (widget.searchConfig.pageScene == PageScene.feedback) {
      navigationBarTitle = "上报地点错误";
    }
    return Scaffold(
      appBar: navigationBarTitle.isNotEmpty
          ? AppBar(
              title: Text(
                navigationBarTitle,
                style: const TextStyle(
                  color: LucyColors.lucy_02102A,
                  fontSize: LucyFonts.size_18,
                  fontWeight: LucyFonts.semi_bold,
                ),
              ),
              backgroundColor: Colors.white,
              leading: T3GestureDetector(
                onTap: () {
                  BoostNavigator.instance.pop();
                },
                child: SizedBox(
                  width: 24,
                  height: 24,
                  child:
                      T3Image.t3assets(T3AssetsName.icon_back_elderly_slices),
                ),
              ),
              elevation: 0,
            )
          : null,
      resizeToAvoidBottomInset: false,
      backgroundColor: LucyColors.lucy_F7F9FC,
      body: buildBody(context, navigationBarTitle),
    );
  }

  Column buildBody(BuildContext buildContext, String navigationBarTitle) {
    var bottomHeight = MediaQuery.of(context).padding.bottom +
        InputConst.kBottomFeedBackButtonHeight;
    return Column(
      children: [
        SearchBarWidget(
            searchConfig: widget.searchConfig,
            showAppBar: navigationBarTitle.isNotEmpty,
            clickCancel: controller.clickCancel,
            viewModel: controller.searchViewModel,
            airportCityChangeCallback: (city, item) {
              controller.airportCityChanged(buildContext, city, item);
            },
            onFinishSelection: onFinishSelection,
            searchConditionChanged: controller.searchConditionChanged),
        Flexible(
          flex: 1,
          child: Stack(
            fit: StackFit.expand,
            children: [
              Container(
                padding: const EdgeInsets.only(left: 12, right: 12),
                child: Obx(() {
                  return CustomScrollView(
                      controller: _scrollController,
                      slivers: [
                        if (controller.pageViewModel.showEntryItems)
                          SliverToBoxAdapter(
                            child: EntryWidget(
                                items:
                                    controller.pageViewModel.entryItems.value),
                          ),
                        if (!controller.pageViewModel.showEntryItems)
                          const SliverToBoxAdapter(
                              child: SizedBox(
                            height: 12,
                          )),
                        if (controller.pageViewModel.showEmpty)
                          ..._buildEmptyWidget(),
                        if (controller.pageViewModel.sections.value.isNotEmpty)
                          ..._buildSections(
                              controller.pageViewModel.sections.value),
                        SliverToBoxAdapter(
                          child: SizedBox(
                            height: bottomHeight,
                          ),
                        ),
                      ]);
                }),
              ),
              _buildShadowWidget(),
              if (widget.searchConfig.pageScene != PageScene.feedback)
                _buildFeedbackWidget(),
            ],
          ),
        )
      ],
    );
  }

  _buildShadowWidget() {
    return Positioned(
      top: -2,
      child: Container(
        height: 2,
        decoration: BoxDecoration(
          color: Colors.red,
          boxShadow: [
            BoxShadow(
                color: const Color(0xFF313854).withOpacity(0.5),
                offset: const Offset(0.0, 2.0),
                blurRadius: 4.0)
          ],
        ),
      ),
    );
  }

  _buildEmptyWidget() {
    List<Widget> slivers = [];
    slivers.add(const SliverToBoxAdapter(
        child: SizedBox(
      height: 12,
    )));

    if (widget.searchConfig.showMapSelectedFooter) {
      T3Track.trackExpose("0199.008.000.022");
      var footerModel = POIListSectionFooterModel(
          title: '去地图上选终点',
          type: POIFooterType.mapSelect,
          imageName: T3AssetsName.search_map_entry);
      slivers.add(POIFooter(
          footModel: footerModel,
          noCorners: true,
          callback: (footType) {
            controller.clickFooter(context, footType, []);
          }));
      slivers.add(const SliverToBoxAdapter(
          child: SizedBox(
        height: 12,
      )));
    }

    slivers.add(SliverToBoxAdapter(
      child: Column(
        children: [
          const SizedBox(
            height: 50,
          ),
          T3Image.t3assets(T3AssetsName.img_noanswer),
          const SizedBox(
            height: 12,
          ),
          const Text(
            '暂无搜索结果，换个词再试试吧',
            style: TextStyle(
                color: Color(0xffa5a7ad),
                fontSize: 14,
                fontWeight: LucyFonts.regular),
          ),
        ],
      ),
    ));
    return slivers;
  }

  List<Widget> _buildSections(List<POIListSection> sections) {
    List<Widget> slivers = [];

    for (var element in sections) {
      if (element.hasHeader) {
        /// 列表的头部
        slivers.add(POIHeader(
          header: element.headerModel!,
          list: element.list,
          callback: (type, list) {
            controller.clickHeader(context, type, list);
          },
        ));
        if (element.headerModel!.needDivider) {
          slivers.add(const SliverToBoxAdapter(
              child: Divider(
            indent: 16,
            height: 1,
          )));
        }
      }

      /// 列表内容
      var showList = element.list;
      if (element.category == T3POICategory.enterprise) {
        if (showList.length > 3) {
          showList = showList.sublist(0, 3);
        }
      }
      slivers.add(SliverList(
          delegate: SliverChildBuilderDelegate(childCount: showList.length,
              (context, index) {
        final e = showList[index];
        e.poi.runtimeParams.spmIsExposure = true;
        if (e.poi.canDelete &&
            (widget.searchConfig.pageScene != PageScene.feedback)) {
          return _buildSlidableCell(e, element, context);
        } else {
          return _buildNormalCell(e, context);
        }
      })));

      /// 列表尾部
      if (element.hasFooter) {
        slivers.add(POIFooter(
            footModel: element.footerModel!,
            callback: (footType) {
              controller.clickFooter(context, footType, element.list);
            }));
        slivers.add(const SliverToBoxAdapter(
            child: SizedBox(
          height: 12,
        )));
      } else {
        /// 空白
        slivers.add(const SliverToBoxAdapter(
            child: SizedBox(
          height: 12,
        )));
      }
    }
    return slivers;
  }

  _buildSlidableCell(
      POISearchCellViewModel e, POIListSection section, BuildContext context) {
    return T3GestureDetector(
      onTap: () {
        controller.didSelectedPOI(e);
      },
      child: Slidable(
        enabled: true,
        endActionPane: ActionPane(
          extentRatio: 0.35,
          motion: const DrawerMotion(),
          children: [
            CustomSlidableAction(
              onPressed: (context) {
                controller.deletePOI(e, section);
              },
              autoClose: true,
              padding: const EdgeInsets.only(left: 0),
              backgroundColor: Colors.transparent,
              child: Container(
                height: double.infinity,
                width: double.infinity,
                decoration: BoxDecoration(
                  color: LucyColors.lucy_F23D33,
                  borderRadius: BorderRadius.circular(8),
                ),
                child: const Center(child: Text("删除")),
              ),
            )
          ],
        ),
        child: T3POICell(
          vm: e,
          config: widget.searchConfig,
          onSelectSubPoi: (subIndex) {
            e.selectedSubPOIIndex = subIndex;
            controller.didSelectedPOI(e);
          },
          keyword: controller.pageViewModel.currentKeyword,
          clickShareButton: (poi) {
            controller.clickSharePOI(context, poi);
          },
        ),
      ),
    );
  }

  _buildNormalCell(POISearchCellViewModel e, BuildContext context) {
    return T3GestureDetector(
      onTap: () {
        var vm = e.copy();
        controller.didSelectedPOI(vm);
      },
      child: T3POICell(
        vm: e,
        config: widget.searchConfig,
        onSelectSubPoi: (subIndex) {
          var vm = e.copy();
          vm.selectedSubPOIIndex = subIndex;
          controller.didSelectedPOI(vm);
        },
        keyword: controller.pageViewModel.currentKeyword,
        clickShareButton: (poi) {
          controller.clickSharePOI(context, poi);
        },
      ),
    );
  }

  _buildFeedbackWidget() {
    if (!didExposureFeedback) {
      didExposureFeedback = true;
      if (widget.searchConfig.isStartPoint) {
        T3Track.trackEventName('019900600001401');
      } else {
        T3Track.trackEventName('019900800002701');
      }
    }
    return Positioned(
      left: 0,
      right: 0,
      bottom: MediaQuery.of(context).padding.bottom + 40,
      child: T3GestureDetector(
        onTap: () {
          controller.clickFeedback();
        },
        child: Container(
          alignment: Alignment.center,
          child: Container(
            decoration: BoxDecoration(
                color: const Color(0xFFFFFFFF),
                borderRadius: const BorderRadius.all(Radius.circular(
                    InputConst.kBottomFeedBackButtonHeight / 2)),
                boxShadow: [
                  BoxShadow(
                      color: const Color(0xFF313854).withOpacity(0.5),
                      offset: const Offset(2.0, 2.0),
                      blurRadius: 4.0)
                ]),
            height: InputConst.kBottomFeedBackButtonHeight,
            width: 140,
            padding: const EdgeInsets.only(left: 8, right: 8),
            child: Row(
              children: [
                T3Image.t3assets(T3AssetsName.error_icon),
                const Text(
                  ' 我要上报地点错误',
                  style: TextStyle(
                    color: Color(0xFF1D2232),
                    fontSize: 12.0,
                  ),
                  textAlign: TextAlign.center,
                )
              ],
            ),
          ),
        ),
      ),
    );
  }
}
